package cn.dengta.webapp.trade.entity;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;

import cn.dengta.common.model.ValueProxy;
import cn.dengta.common.util.BeanUtil;
import cn.dengta.common.util.Formats;
import cn.dengta.context.model.LabelI18nProxy;
import cn.dengta.webapp.base.entity.TimeBasedEntity;
import cn.dengta.webapp.trade.model.CashSubTypeMethod;
import cn.dengta.webapp.trade.model.PaymentMethod;
import cn.dengta.webapp.trade.form.BindBankCardForm;
import cn.dengta.webapp.trade.form.PayerMaxReqForm;
import cn.dengta.webapp.trade.model.PayPlatform;
import cn.dengta.webapp.user.entity.User;
import cn.dengta.webapp.user.model.CertType;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import me.codeplayer.util.X;

/**
 * 提现账号
 *
 * @author yuqidi
 * @since 2022-03-24
 */
@Setter
@Getter
@Accessors(chain = true)
@TableName("tr_cash_account")
public class CashAccount extends TimeBasedEntity {

	/** 用户ID */
	private Long userId;
	/**
	 * 支付平台
	 *
	 * @see cn.dengta.webapp.trade.model.PayPlatform
	 */
	private Integer platform;
	/** 国家 */
	private String country;

	private String certNo;

	/** 证件类型 */
	private CertType certType;
	/**
	 * 1=银行卡；2=钱包；3支付宝
	 *
	 * @see PaymentMethod
	 */
	private Integer type;
	/** 子类型，根据国家与类型 来确定, 0=默认值，不代表业务含义 */
	private CashSubTypeMethod subType;
	/** 是否主账户：0=不是；1=主账户 */
	private Integer master;
	/** 手机号 */
	private String phone;
	/** 真实姓名 */
	private String realName;
	/** 提现账号 */
	private String account;

	/** 提现币种 */
	private String currency;
	/** 银行卡Code */
	private String bankCode;
	/** 第一个名称 */
	private String firstName;
	/** 最后一个名称 */
	private String lastName;
	/** 中间名 */
	private String middleName;
	/** 银行的ifsc */
	private String ifscCode;
	/** 邮箱 */
	private String email;
	/** 地址 */
	private String address;


	/** 副本来源ID */
	private Long oldCopyId;
	/** 业务状态：-1=无效（应账户不对导致提现失败）；0=初始化；1=有效（已经提现成功过） */
	private Integer status;
	/** 审核人 */
	protected Long verifyUserId;
	/** 审核备注 */
	protected String verifyRemark;
	/** 审核时间 */
	protected Date verifyTime;

	private String zipCode;
	private String addrCity;
	private String addrState;
	/**
	 * C: for Checking accounts P: for Savings accounts
	 */
	private String accType;
	private String docType;
	private String docId;
	private String bankBranch;
	private String checkDigit;





	public CashAccount init(CashAccount input, Date now) {
		this.userId = X.expectNotNull(userId, input.userId);
		this.platform = X.expectNotNull(platform, input.platform);
		this.phone = X.expectNotNull(input.phone, phone, "");
		this.realName = X.expectNotNull(input.realName, realName);
		this.account = X.expectNotNull(input.account, account);
		this.verifyRemark = X.expectNotNull(input.verifyRemark, "");
		this.currency = X.expectNotNull(input.currency, currency);
		this.bankCode = X.expectNotNull(input.getBankCode(), bankCode);
		this.accType = X.expectNotNull(input.getAccType(), accType);
		this.docType = X.expectNotNull(input.getDocType(), docType);
		this.docId = X.expectNotNull(input.getDocId(), docId);
		this.zipCode = X.expectNotNull(input.getZipCode(), zipCode);
		this.addrCity = X.expectNotNull(input.getAddrCity(), addrCity);
		this.addrState = X.expectNotNull(input.getAddrState(), addrState);
		this.bankBranch = X.expectNotNull(input.getBankBranch(), bankBranch);
		this.checkDigit = X.expectNotNull(input.getCheckDigit(), checkDigit);
		this.status = X.expectNotNull(input.status, status, CashAccountStatus.INVALID.value); // 默认是无效的
		super.initTime(now);
		return this;
	}

	public PayerMaxReqForm toPayerMaxReqForm(String orderNo, BigDecimal realCash) {
		if (platform.equals(PayPlatform.PayerMax.value)) {
			PayerMaxReqForm form = new PayerMaxReqForm();
			form.setAccountId(this.id);
			form.setOrderNo(orderNo);
			form.setAccountNo(this.account);
			form.setAccType(this.accType);
			form.setDocType(this.docType);
			form.setDocId(this.docId);
			form.setBankBranch(this.bankBranch);
			form.setCheckDigit(this.checkDigit);
			form.setZipCode(this.zipCode);
			form.setAddrCity(this.addrCity);
			form.setAddrState(this.addrState);
			form.setTargetOrg(this.bankCode);
			form.setIfscCode(this.ifscCode);
			form.setCountry(this.country);
			form.setCurrency(this.currency);
			form.setFirstName(this.firstName);
			form.setLastName(this.lastName);
			form.setMiddleName(this.middleName);
			form.setPhone(this.phone);
			form.setEmail(this.email);
			form.setAddress(this.address);
			form.setPaymentMethod(PaymentMethod.of(this.getType()));
			form.buildAmount(realCash);
			return form;
		}
		return null;
	}

	public static CashAccount bindBankCardForm(BindBankCardForm form, User user) {
		CashAccount cashAccount = new CashAccount();
		BeanUtil.copyProperties(form, cashAccount);
		cashAccount.setRealName("");
		cashAccount.setPlatform(PayPlatform.PayerMax.value)
				.setUserId(user.getId())
				.setType(form.getFormType())
				.setSubType(CashSubTypeMethod.ofLabel(form.getSubType()))
				.setStatus(CashAccountStatus.VALID.value);
		cashAccount.initTime(new Date());
		return cashAccount;
	}

	public boolean contentEquals(CashAccount b) {
		if (this == b) {
			return true;
		}
		if (b == null) {
			return false;
		}
		return Objects.equals(platform, b.platform)
				&& Objects.equals(phone, b.phone)
				&& Objects.equals(realName, b.realName)
				&& Objects.equals(account, b.account)
				&& Objects.equals(currency, b.currency)
				&& Objects.equals(bankCode, b.bankCode);
	}

	public boolean canUnbind() {
		return status >= 0;
	}

	public String getAccount_() {
		return Formats.anonymousBankAccount(account);
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Getter
	public enum CashAccountStatus implements LabelI18nProxy<CashAccountStatus, Integer> {
		/** 无效 */
		INVALID(-1, "无效"),
		/** 初始化 */
		WAIT_VERIFY(0, "初始化"),
		/** 启用 */
		VALID(1, "有效"),
		//
		;
		public final Integer value;
		public final ValueProxy<CashAccountStatus, Integer> proxy;

		CashAccountStatus(Integer value, String label) {
			this.value = value;
			this.proxy = new ValueProxy<>(this, value, label);
		}

		public static CashAccountStatus[] getValues() {
			return ValueProxy.getCachedArray(CashAccountStatus.class, CashAccountStatus::values);
		}

		public static CashAccountStatus of(Integer value) {
			return VALID.getValueOf(value);
		}
	}

	public static final String USER_ID = "user_id";
	public static final String PLATFORM = "platform";
	public static final String MASTER = "master";
	public static final String PHONE = "phone";
	public static final String REAL_NAME = "real_name";
	public static final String ACCOUNT = "account";
	public static final String CURRENCY = "currency";
	public static final String OLD_COPY = "old_copy";
	public static final String STATUS = "status";
	public static final String COUNTRY = "country";
	public static final String TYPE = "type";
	public static final String SUB_TYPE = "sub_type";

}
